<!DOCTYPE html>
<html lang="zh-CN" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>JavaScript中的正则表达式 | Nuobel</title>
    <meta name="description" content="Nuobel 诺贝尔的源泉">
    <link rel="preload stylesheet" href="/assets/style.6550a0c8.css" as="style">
    <link rel="modulepreload" href="/assets/app.6facf8ba.js">
    <link rel="modulepreload" href="/assets/blog_2020_07_regex-in-javascript.md.375103f6.lean.js">
    
    <meta name="theme-color" content="#3c8772">
  <script>var _hmt=_hmt||[];(function(){var e=document.createElement("script");e.src="https://hm.baidu.com/hm.js?b812ad2761f4f77a87ce9b80c0cae4a0";var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)})();</script>
  <script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-93a960b4><!--[--><!--]--><!--[--><span tabindex="-1" data-v-151f2593></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-151f2593> Skip to content </a><!--]--><!----><header class="VPNav" data-v-93a960b4 data-v-0fa0e57d><div class="VPNavBar has-sidebar" data-v-0fa0e57d data-v-be450ad9><div class="container" data-v-be450ad9><div class="title" data-v-be450ad9><div class="VPNavBarTitle has-sidebar" data-v-be450ad9 data-v-6d2fb2d9><a class="title" href="/" data-v-6d2fb2d9><!--[--><!--]--><!----><!--[-->Nuobel<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-be450ad9><div class="curtain" data-v-be450ad9></div><div class="content-body" data-v-be450ad9><!--[--><!--]--><!----><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-be450ad9 data-v-bdedfc22><span id="main-nav-aria-label" class="visually-hidden" data-v-bdedfc22>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink active" href="/blog/frontend/library.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->博客<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/blog/summary/20210806.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->日记周记<!--]--><!----></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-bdedfc22 data-v-96001b6b><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-96001b6b><span class="text" data-v-96001b6b><!----> 读书笔记 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-96001b6b><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-96001b6b><div class="VPMenu" data-v-96001b6b data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-b66affaf><p class="title" data-v-b66affaf>前端技术</p><!--[--><!--[--><div class="VPMenuLink" data-v-b66affaf data-v-a5bbb52c><a class="VPLink link" href="/blog/svg/rumen.html" data-v-a5bbb52c data-v-30c06bd3><!--[-->SVG基础入门<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b66affaf data-v-a5bbb52c><a class="VPLink link" href="/blog/readingNotes/browserPrinciple.html" data-v-a5bbb52c data-v-30c06bd3><!--[-->浏览器工作原理与实践<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b66affaf data-v-a5bbb52c><a class="VPLink link" href="/blog/readingNotes/reactAndNodeJS.html" data-v-a5bbb52c data-v-30c06bd3><!--[-->react+Node.js开发实战<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b66affaf data-v-a5bbb52c><a class="VPLink link" href="/blog/readingNotes/jsgc4.html" data-v-a5bbb52c data-v-30c06bd3><!--[-->javascript高级程序设计第4版<!--]--><!----></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/blog/interviews/" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->面试<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/photograph/home.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->摄影<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/english/plan.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->英语<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/wemedia/what.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->自媒体<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/life/index.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->生活<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/about/me.html" data-v-bdedfc22 data-v-95f5d58b data-v-30c06bd3><!--[-->关于 <!--]--><!----></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-be450ad9 data-v-da3f667a><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-da3f667a data-v-0d529b6d data-v-f3c41672><span class="check" data-v-f3c41672><span class="icon" data-v-f3c41672><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-0d529b6d><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-0d529b6d><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><!----><div class="VPFlyout VPNavBarExtra extra" data-v-be450ad9 data-v-66bb1f24 data-v-96001b6b><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-96001b6b><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-96001b6b><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-96001b6b><div class="VPMenu" data-v-96001b6b data-v-e7ea1737><!----><!--[--><!--[--><!----><div class="group" data-v-66bb1f24><div class="item appearance" data-v-66bb1f24><p class="label" data-v-66bb1f24>Appearance</p><div class="appearance-action" data-v-66bb1f24><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-66bb1f24 data-v-0d529b6d data-v-f3c41672><span class="check" data-v-f3c41672><span class="icon" data-v-f3c41672><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-0d529b6d><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-0d529b6d><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><!----><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-be450ad9 data-v-e5dd9c1c><span class="container" data-v-e5dd9c1c><span class="top" data-v-e5dd9c1c></span><span class="middle" data-v-e5dd9c1c></span><span class="bottom" data-v-e5dd9c1c></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav" data-v-93a960b4 data-v-2817d72e><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-2817d72e><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-2817d72e><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-2817d72e>菜单</span></button><a class="top-link" href="#" data-v-2817d72e>回到顶部</a></div><aside class="VPSidebar" data-v-93a960b4 data-v-c79ccefa><div class="curtain" data-v-c79ccefa></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-c79ccefa><span class="visually-hidden" id="sidebar-aria-label" data-v-c79ccefa> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-c79ccefa><section class="VPSidebarItem level-0 has-active" data-v-c79ccefa data-v-b05232f3><div class="item" role="button" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link" data-v-b05232f3 data-v-30c06bd3><!--[--><h2 class="text" data-v-b05232f3>前端技术</h2><!--]--><!----></a><!----></div><div class="items" data-v-b05232f3><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/frontend/library.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>前端常用资源汇总</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/11/webpack-how-to-load-chunks.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>webpack是怎么加载模块的</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/07/throttle-and-debounce.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>节流和防抖技术</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link is-active has-active" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/07/regex-in-javascript.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>JavaScript中的正则表达式</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/07/http-cache-and-nginx-config.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>http缓存与nginx配置</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/07/use-react-framework-web-site.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>使用react框架构建的知名站点</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/06/gatsby-markdown-blog-system.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>使用gatsby搭建博客网站系统</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-c79ccefa><section class="VPSidebarItem level-0" data-v-c79ccefa data-v-b05232f3><div class="item" role="button" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link" data-v-b05232f3 data-v-30c06bd3><!--[--><h2 class="text" data-v-b05232f3>服务端技术</h2><!--]--><!----></a><!----></div><div class="items" data-v-b05232f3><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/06/ubuntu14.04-install-nginx-for-source-code.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>ubuntu14.04源码编译安装nginx</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-c79ccefa><section class="VPSidebarItem level-0" data-v-c79ccefa data-v-b05232f3><div class="item" role="button" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link" data-v-b05232f3 data-v-30c06bd3><!--[--><h2 class="text" data-v-b05232f3>使用文档</h2><!--]--><!----></a><!----></div><div class="items" data-v-b05232f3><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/08/fiddler.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>fiddler的使用</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/07/git-docs.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>git使用基础文档</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/07/css-modules-docs.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>css-modules使用基础文档</p><!--]--><!----></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b05232f3 data-v-b05232f3><div class="item" data-v-b05232f3><div class="indicator" data-v-b05232f3></div><a class="VPLink link link" href="/blog/2020/07/vim-docs.html" data-v-b05232f3 data-v-30c06bd3><!--[--><p class="text" data-v-b05232f3>vim使用基础文档</p><!--]--><!----></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-93a960b4 data-v-0bd490fb><div class="VPDoc has-sidebar has-aside" data-v-0bd490fb data-v-c5936a1e><div class="container" data-v-c5936a1e><div class="aside" data-v-c5936a1e><div class="aside-curtain" data-v-c5936a1e></div><div class="aside-container" data-v-c5936a1e><div class="aside-content" data-v-c5936a1e><div class="VPDocAside" data-v-c5936a1e data-v-cdc66372><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" data-v-cdc66372 data-v-5dd9d5f6><div class="content" data-v-5dd9d5f6><div class="outline-marker" data-v-5dd9d5f6></div><div class="outline-title" data-v-5dd9d5f6>本页目录</div><nav aria-labelledby="doc-outline-aria-label" data-v-5dd9d5f6><span class="visually-hidden" id="doc-outline-aria-label" data-v-5dd9d5f6> Table of Contents for current page </span><ul class="root" data-v-5dd9d5f6 data-v-1188541a><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-cdc66372></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-c5936a1e><div class="content-container" data-v-c5936a1e><!--[--><!--]--><main class="main" data-v-c5936a1e><div style="position:relative;" class="vp-doc _blog_2020_07_regex-in-javascript" data-v-c5936a1e><div><p>正则表达式是一个高效的工具，是一种描述字符串数据中的模式的方法。它们形成一种小而独立的语言，是 JavaScript 和许多其它语言和系统的一部分。</p><p>下面我们将正确理解正则表达式在 JavaScript 中的应用</p><h2 id="创建正则表达式" tabindex="-1">创建正则表达式 <a class="header-anchor" href="#创建正则表达式" aria-hidden="true">#</a></h2><p>有两种方式来创建正则表达式</p><h3 id="regexp-构造函数方式" tabindex="-1">RegExp 构造函数方式 <a class="header-anchor" href="#regexp-构造函数方式" aria-hidden="true">#</a></h3><p>构造函数<code>RegExp</code>接收两个参数，第一个是要匹配的<strong>字符串</strong>模式,第二个是可选的标志字符串。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 构造函数示例</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> re1 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">RegExp</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">abc</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">i</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><h3 id="字面量方式" tabindex="-1">字面量方式 <a class="header-anchor" href="#字面量方式" aria-hidden="true">#</a></h3><ul><li>语法 <blockquote><p>let expression = /pattern/flags</p></blockquote></li></ul><p>其中 pattern 是模式部分,flags 是标志部分</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 示例</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> re2 </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">abc</span><span style="color:#89DDFF;">/</span><span style="color:#F78C6C;">g</span></span>
<span class="line"></span></code></pre></div><h3 id="两种方式的区别" tabindex="-1">两种方式的区别 <a class="header-anchor" href="#两种方式的区别" aria-hidden="true">#</a></h3><p>两种方式创建出的 re1 和 re2 都是 RegExp 的实例，都有 RegExp 实例的属性和方法</p><p>区别是构造函数的参数都是字符串的形式,所以在匹配元字符时需要使用双重转义。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 如下，我们书写匹配\[bc\]at字符串的正则</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 字面量模式</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> p1 </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#A6ACCD;">\[</span><span style="color:#C3E88D;">bc</span><span style="color:#A6ACCD;">\]</span><span style="color:#C3E88D;">at</span><span style="color:#89DDFF;">/</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 等价的字符串模式</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> p2 </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">new</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">RegExp</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">\\</span><span style="color:#C3E88D;">[bc</span><span style="color:#A6ACCD;">\\</span><span style="color:#C3E88D;">]at</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><h2 id="正则表达式知识点" tabindex="-1">正则表达式知识点 <a class="header-anchor" href="#正则表达式知识点" aria-hidden="true">#</a></h2><h3 id="标志位" tabindex="-1">标志位 <a class="header-anchor" href="#标志位" aria-hidden="true">#</a></h3><p>前面我们知道，正则表达式都有可选的标志位，标志位表明正则表达式的行为，取值如下：</p><table><thead><tr><th>取值</th><th>描述</th></tr></thead><tbody><tr><td><strong>g</strong></td><td>表示全局模式，即模式被应用于所有字符串,而不是在发现第一个匹配项时立即停止。</td></tr><tr><td><strong>i</strong></td><td>表示不区分大小写模式</td></tr><tr><td><strong>m</strong></td><td>多行模式，在到达一行文本末尾时，还会继续查找下一行中是否存在与模式匹配的项</td></tr></tbody></table><h3 id="元字符" tabindex="-1">元字符 <a class="header-anchor" href="#元字符" aria-hidden="true">#</a></h3><p>正则表达式的元字符在模式中都有一种或多种用途，如下：</p><blockquote><p>()[]{}\^$|?*+.</p></blockquote><p>如果你想匹配字符串中的元字符，则必须使用反斜杠(\)对它们进行转义</p><h3 id="字符集" tabindex="-1">字符集 <a class="header-anchor" href="#字符集" aria-hidden="true">#</a></h3><p>**方括号[]**之间的字符集使模式的一部分与字符串中的任何字符匹配</p><p>说白话就是字符串在方括号这个位置的字符串，只要满足方括号中列出的任一个字符，就匹配。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 下面两个表达式都匹配包含数字的字符串</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/[</span><span style="color:#C3E88D;">0123456789</span><span style="color:#89DDFF;">]/</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">gafgsd3</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/[</span><span style="color:#C3E88D;">0-9</span><span style="color:#89DDFF;">]/</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">sdfs4</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"></span></code></pre></div><p>在方括号中，两个字符之间的连字符**&quot;-&quot;<strong>,用于表示</strong>按字符的 Unicode 编码确定顺序**的字符范围。 如上面的字符 0-9 在 Unicode 中相邻（代码 48-57）,因此[0-9]涵盖所有数字</p><p>许多常见的角色组都有自己的内置快捷键方式。数字就是其中之一：\d 和[0-9]匹配内容相同。</p><blockquote><p>**注意：**方括号中的元字符会失去它的特殊意义<br>如[\d.+]，表示任意数字、句点或加号。</p></blockquote><ul><li>常见字符集快捷方式列表:</li></ul><table><thead><tr><th>快捷方式</th><th>描述</th></tr></thead><tbody><tr><td>\d</td><td>任何数字字符</td></tr><tr><td>\w</td><td>匹配字母、数字、下划线，相当于<code>[a-zA-Z0-9_]</code></td></tr><tr><td>\s</td><td>任何空白字符（空格、制表符、换行符和类似字符），相当于<code>[\f\n\r\t\v]</code></td></tr><tr><td>\D</td><td>非数字的字符</td></tr><tr><td>\W</td><td>非字母、数字、下划线，相当于<code>[^a-za-z0-9_]</code></td></tr><tr><td>\S</td><td>非空白字符</td></tr><tr><td>.</td><td>除换行符外的任何字符</td></tr><tr><td>\uhhhh</td><td>表示匹配以十六进制表示的字符的 Unicode 值 ，hhhh 即十六进制值</td></tr></tbody></table><ul><li>取反</li></ul><p>要对一组字符取反，可以在左方括号初加一个插入符号^，表示不是后面的一系列字符</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 下面的正则表达式匹配非a、b、或c字符</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 即只要字符串里有不是a、b或c字符，就匹配</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/[^</span><span style="color:#C3E88D;">abc</span><span style="color:#89DDFF;">]/</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">a</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/[^</span><span style="color:#C3E88D;">abc</span><span style="color:#89DDFF;">]/</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">ad</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"></span></code></pre></div><h3 id="模式中的重复" tabindex="-1">模式中的重复 <a class="header-anchor" href="#模式中的重复" aria-hidden="true">#</a></h3><p>先看一个匹配年月日的例子</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> re </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">\d\d\d\d-\d\d-\d\d</span><span style="color:#89DDFF;">/</span></span>
<span class="line"><span style="color:#A6ACCD;">re</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">2020-07-18</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"></span></code></pre></div><p>这样是没问题，但会不会看起来很糟糕？重复的太多</p><p>正则表达式中的重复能让模式看起来更优雅，如下:</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> re </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">\d</span><span style="color:#89DDFF;">{4}</span><span style="color:#C3E88D;">-\d</span><span style="color:#89DDFF;">{2}</span><span style="color:#C3E88D;">-\d</span><span style="color:#89DDFF;">{2}/</span></span>
<span class="line"><span style="color:#A6ACCD;">re</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">2020-07-18</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"></span></code></pre></div><p>下面列出常用的表达重复的元字符(表明该重复元字符**前面的字符（组）**重复多少次)：</p><table><thead><tr><th>字符</th><th>描述</th></tr></thead><tbody><tr><td>+</td><td>表示重复 1 次或多次</td></tr><tr><td>*</td><td>表示 0 个及以上</td></tr><tr><td>?</td><td>表示 0 次或 1 次</td></tr><tr><td><code>{4}</code></td><td>恰好出现 4 次</td></tr><tr><td><code>{1,4}</code></td><td>最少 1 次，最多 4 次</td></tr><tr><td><code>{2,}</code></td><td>2 次及以上</td></tr></tbody></table><h3 id="分组" tabindex="-1">分组 <a class="header-anchor" href="#分组" aria-hidden="true">#</a></h3><p>前面介绍的重复元字符，都是表明它前面单个字符的重复次数</p><p>如果想要多个字符一起运用重复元字符，则需要用到<strong>圆括号()</strong>，组成一个组</p><p>如下示例：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> re </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">boo</span><span style="color:#89DDFF;">+(</span><span style="color:#C3E88D;">hoo</span><span style="color:#89DDFF;">+)+/</span></span>
<span class="line"><span style="color:#A6ACCD;">re</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">boohooohooo</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"></span></code></pre></div><p>上面的例子第一个和第二个+仅适用于 boo 和 hoo 的第二个 o 的重复次数，而第三个+，则表示整个组(hoo+)重复 1 到多次。</p><p>分组的另一个用处是在 RegExp 实例的 <a href="#exec-%E6%96%B9%E6%B3%95">exec 方法</a> 里</p><h3 id="单词和字符串边界" tabindex="-1">单词和字符串边界 <a class="header-anchor" href="#单词和字符串边界" aria-hidden="true">#</a></h3><p>一些情况下，我们需要强制整个字符串匹配，我们可以使用**^和$**标记</p><p>^表示匹配输入字符串的开头，而美元字符串$与结尾匹配</p><p>如下：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;font-style:italic;">^</span><span style="color:#C3E88D;">!</span><span style="color:#89DDFF;">/</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 匹配以感叹号开头的字符串</span></span>
<span class="line"><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;font-style:italic;">^</span><span style="color:#C3E88D;">\d</span><span style="color:#89DDFF;">+</span><span style="color:#89DDFF;font-style:italic;">$</span><span style="color:#89DDFF;">/</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 匹配完全由数字组成的字符串</span></span>
<span class="line"><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">x</span><span style="color:#89DDFF;font-style:italic;">^</span><span style="color:#89DDFF;">/</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 与任何字符串都不匹配，字符串开头不可能有x</span></span>
<span class="line"></span></code></pre></div><p>还有一种，我们只想确保匹配的模式在单词边界上开始和结束，这时可以使用标记**\b**</p><p>先看下面的年月日匹配：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> re1 </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">\d</span><span style="color:#89DDFF;">{4}</span><span style="color:#C3E88D;">-\d</span><span style="color:#89DDFF;">{2}</span><span style="color:#C3E88D;">-\d</span><span style="color:#89DDFF;">{2}/</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">match</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> re1</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">exec</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">in 2020-07-18</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(match) </span><span style="color:#676E95;font-style:italic;">// 2020-07-18</span></span>
<span class="line"></span></code></pre></div><p>看起来没什么问题对吧，如果字符串类似于下面这种呢</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">match</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> re1</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">exec</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">888812-98-99797a</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(match) </span><span style="color:#676E95;font-style:italic;">// 8812-98-99</span></span>
<span class="line"></span></code></pre></div><p>很明显，上面不是我们想要匹配的日期</p><p>此时可以使用单词边界，因为我们匹配的日期两边应该是非单词字符</p><p>也就是有单词边界的,所谓<strong>单词边界</strong>，即字符串中一侧有单词字符（\w），而另一侧为非单词字符的<strong>任何点</strong>。</p><p>当然字符串的开头和结尾也是单词边界</p><p>白话就是\b 两边一边是单词字符，另一边是非单词字符，才能形成边界。</p><p>修正后的日期匹配如下</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> re1 </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;font-style:italic;">\b</span><span style="color:#C3E88D;">\d</span><span style="color:#89DDFF;">{4}</span><span style="color:#C3E88D;">-\d</span><span style="color:#89DDFF;">{2}</span><span style="color:#C3E88D;">-\d</span><span style="color:#89DDFF;">{2}</span><span style="color:#89DDFF;font-style:italic;">\b</span><span style="color:#89DDFF;">/</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> match </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> re1</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">exec</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">888812-98-99797a</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(match) </span><span style="color:#676E95;font-style:italic;">// null</span></span>
<span class="line"></span></code></pre></div><p>另外<code>\B</code>是匹配非单词边界，如<code>er\B</code>能匹配<code>very</code>但不能匹配<code>ver ss</code></p><h3 id="选择模式" tabindex="-1">选择模式 <a class="header-anchor" href="#选择模式" aria-hidden="true">#</a></h3><p>选择模式就是备选方案，也可以想成或运算符</p><p><strong>管道符（|）</strong>，可以让我们在它的左侧和右侧模式之间做出一个选择.</p><p>如下示例：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> animalCount </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">\d</span><span style="color:#89DDFF;">+(</span><span style="color:#C3E88D;">只</span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;">条</span><span style="color:#89DDFF;">)(</span><span style="color:#C3E88D;">熊猫</span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;">猴子</span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;">鳄鱼</span><span style="color:#89DDFF;">)/</span></span>
<span class="line"><span style="color:#A6ACCD;">animalCount</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">12只猴子</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#A6ACCD;">animalCount</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">5条鳄鱼</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#A6ACCD;">animalCount</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">5根鳄鱼</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"></span></code></pre></div><h3 id="贪心" tabindex="-1">贪心 <a class="header-anchor" href="#贪心" aria-hidden="true">#</a></h3><p>重复运算符（元字符）（<strong>+ * ? 和{}</strong>）是贪心的，它们会尽可能多的匹配。</p><p>看如下示例：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 匹配并替换js文本中的所有注释</span></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">stripComments</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">code</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">replace</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">/</span><span style="color:#A6ACCD;">\/\/</span><span style="color:#C3E88D;">.</span><span style="color:#89DDFF;">*|</span><span style="color:#A6ACCD;">\/\*</span><span style="color:#89DDFF;">[^]*</span><span style="color:#A6ACCD;">\*\/</span><span style="color:#89DDFF;">/</span><span style="color:#F78C6C;">g</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;&quot;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">stripComments</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">1+2//abcd...</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// 1+2</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 下面这个期望输出1+2,实际输出12</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">stripComments</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">1/*haha*/+/*hehe*/2</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">))</span></span>
<span class="line"></span></code></pre></div><p>上面的例子看出，在匹配多行注释时，和我们的预期不一致，中间的+也被替换掉，很明显太贪心，[^]*中的*会尽可能多的匹配,它匹配完 haha 后，发现后面的*/也满足，就会继续匹配。但这并不是我们想要的。</p><p>如果我们在重复运算符后面加一个?，那么它将变得不贪心，并且尽可能少的匹配</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 匹配并替换js文本中的所有注释</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 注意[^]*多了个问号?</span></span>
<span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">stripComments</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">code</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">code</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">replace</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">/</span><span style="color:#A6ACCD;">\/\/</span><span style="color:#C3E88D;">.</span><span style="color:#89DDFF;">*|</span><span style="color:#A6ACCD;">\/\*</span><span style="color:#89DDFF;">[^]*?</span><span style="color:#A6ACCD;">\*\/</span><span style="color:#89DDFF;">/</span><span style="color:#F78C6C;">g</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&quot;&quot;</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// highlight-line</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 修正后正确输出1+2</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#82AAFF;">stripComments</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">1/*haha*/+/*hehe*/2</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">))</span></span>
<span class="line"></span></code></pre></div><h3 id="前瞻后顾负前瞻负后顾" tabindex="-1">前瞻后顾负前瞻负后顾 <a class="header-anchor" href="#前瞻后顾负前瞻负后顾" aria-hidden="true">#</a></h3><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#676E95;font-style:italic;">// 前瞻,str1后面是str2就匹配str1，检查匹配串的后面是否符合要求</span></span>
<span class="line"><span style="color:#82AAFF;">str1</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">?=</span><span style="color:#A6ACCD;">str2)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 负前瞻,str2前面是str1就匹配str2，检查匹配串的前面是否符合要求</span></span>
<span class="line"><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">?&lt;=</span><span style="color:#A6ACCD;">str1)str2</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 后顾,匹配str1后面不是str2的字符串str1</span></span>
<span class="line"><span style="color:#82AAFF;">str1</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">?!</span><span style="color:#A6ACCD;">str2)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 负后顾,匹配前面不是str1的str2</span></span>
<span class="line"><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">?&lt;!</span><span style="color:#A6ACCD;">str1)str2</span></span>
<span class="line"></span></code></pre></div><p>它们都是非获取匹配，虽然它有圆括号，但该匹配不需要获取供以后使用。同时预查也不消耗字符。</p><p>还有一个<code>(?:pattern)</code>表示匹配但不存储这个捕获组，不能供后面使用。</p><p>应用 1，千位分隔符的实现：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">1234567890</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">replace</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;font-style:italic;">\B</span><span style="color:#89DDFF;">(?=(?:</span><span style="color:#C3E88D;">\d</span><span style="color:#89DDFF;">{3})+(?!</span><span style="color:#C3E88D;">\d</span><span style="color:#89DDFF;">))/</span><span style="color:#F78C6C;">g</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">,</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 一句话理解：查找非单词边界，后面至少有一组3个数字组成的组合，并且这n个组合后面不能是数字，最后替换这个非单词边界为逗号</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 例如1\B234567  这个非单词边界就能替换为逗号，因为 234567是2个三个数字组成的组合，组后后也不是数字</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 例如1\B2345678  这个1后面的非单词边界就不能替换为逗号，因为 234567虽然可以满足(?:\d{3})+，但不满足(?!\d)</span></span>
<span class="line"></span></code></pre></div><p>应用 2，1-10 为数字字母组成，前面必须是下划线</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> reg </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/(?&lt;=</span><span style="color:#C3E88D;">_</span><span style="color:#89DDFF;">)[</span><span style="color:#C3E88D;">a-zA-Z0-9</span><span style="color:#89DDFF;">]{1,10}/</span></span>
<span class="line"><span style="color:#A6ACCD;">reg</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">g4</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"><span style="color:#A6ACCD;">reg</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">_g4</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#A6ACCD;">reg</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">g4_</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"></span></code></pre></div><p>应用 3，1-10 为数字字母组成，必须包含大写字母、小写字母和数字</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> reg </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;font-style:italic;">^</span><span style="color:#89DDFF;">(?!</span><span style="color:#89DDFF;font-style:italic;">^</span><span style="color:#89DDFF;">[</span><span style="color:#C3E88D;">a-z0-9</span><span style="color:#89DDFF;">]+</span><span style="color:#89DDFF;font-style:italic;">$</span><span style="color:#89DDFF;">)(?!</span><span style="color:#89DDFF;font-style:italic;">^</span><span style="color:#89DDFF;">[</span><span style="color:#C3E88D;">A-Z0-9</span><span style="color:#89DDFF;">]+</span><span style="color:#89DDFF;font-style:italic;">$</span><span style="color:#89DDFF;">)(?!</span><span style="color:#89DDFF;font-style:italic;">^</span><span style="color:#89DDFF;">[</span><span style="color:#C3E88D;">a-zA-Z</span><span style="color:#89DDFF;">]+</span><span style="color:#89DDFF;font-style:italic;">$</span><span style="color:#89DDFF;">)[</span><span style="color:#C3E88D;">a-zA-Z0-9</span><span style="color:#89DDFF;">]{1,10}</span><span style="color:#89DDFF;font-style:italic;">$</span><span style="color:#89DDFF;">/</span></span>
<span class="line"><span style="color:#A6ACCD;">reg</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">g1a</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">//false</span></span>
<span class="line"><span style="color:#A6ACCD;">reg</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">g1A</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 解释，前面三个预查：</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// (?!^[a-z0-9]+$)  不能是a-z0-9，但最后也说了在[a-zA-Z0-9]中选，结合起来看至少要有一个A-Z了</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">// 后面的(?!^[A-Z0-9]+$) (?!^[a-zA-Z]+$)同理至少要有一个a-z以及至少要有一个0-9</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">//</span></span>
<span class="line"></span></code></pre></div><h2 id="正则表达式对象实例的属性" tabindex="-1">正则表达式对象实例的属性 <a class="header-anchor" href="#正则表达式对象实例的属性" aria-hidden="true">#</a></h2><h3 id="属性列表" tabindex="-1">属性列表 <a class="header-anchor" href="#属性列表" aria-hidden="true">#</a></h3><p>每个正则表达式的实例都具有以下属性</p><table><thead><tr><th>属性</th><th>描述</th></tr></thead><tbody><tr><td><strong>global</strong></td><td>布尔值，表示是否设置了 g 标志</td></tr><tr><td><strong>ignoreCass</strong></td><td>布尔值，表示是否设置了 i 标志</td></tr><tr><td><strong>multiline</strong></td><td>布尔值，表示是否设置了 m 标志</td></tr><tr><td><strong>lastIndex</strong></td><td>整数，表示开始搜索下一个匹配项的字符位置，从 0 开始</td></tr><tr><td><strong>source</strong></td><td>正则表达式的字符串，返回按照字面量形式的模式字符串。</td></tr></tbody></table><p>这些属性很少用到，因为模式已经包含了大部分信息。</p><h2 id="正则表达式对象实例的方法" tabindex="-1">正则表达式对象实例的方法 <a class="header-anchor" href="#正则表达式对象实例的方法" aria-hidden="true">#</a></h2><h3 id="test-方法" tabindex="-1">test 方法 <a class="header-anchor" href="#test-方法" aria-hidden="true">#</a></h3><p>接收一个参数，参数为字符串，它将返回一个 bool 值，告诉你字符串是否符合模式匹配。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">abc</span><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">dabce</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// true</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">abc</span><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">dabFe</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)) </span><span style="color:#676E95;font-style:italic;">// false</span></span>
<span class="line"></span></code></pre></div><h3 id="exec-方法" tabindex="-1">exec 方法 <a class="header-anchor" href="#exec-方法" aria-hidden="true">#</a></h3><p>exec 方法是专门为捕获组而设计的，接收一个参数，即要应用模式的字符串</p><p>如果未匹配，返回 null；匹配则返回一个 Array 的实例，并额外带有 index 和 input 属性</p><p>index 表示匹配项在字符串中的位置，input 表示应用模式的字符串</p><p>在数组中，第一项是与整个模式匹配的字符串，其它项是与模式中捕获组匹配的字符串</p><p>如下示例：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> re </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">who am </span><span style="color:#89DDFF;">(</span><span style="color:#C3E88D;">I</span><span style="color:#89DDFF;">)?/</span><span style="color:#F78C6C;">g</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> result </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> re</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">exec</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">hello who am I?</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">result</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">index </span><span style="color:#676E95;font-style:italic;">// 6</span></span>
<span class="line"><span style="color:#A6ACCD;">result</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">input </span><span style="color:#676E95;font-style:italic;">// hello who am I?</span></span>
<span class="line"><span style="color:#A6ACCD;">result[</span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;">] </span><span style="color:#676E95;font-style:italic;">// who am I</span></span>
<span class="line"><span style="color:#A6ACCD;">result[</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">] </span><span style="color:#676E95;font-style:italic;">// I</span></span>
<span class="line"></span></code></pre></div><blockquote><p><strong>注意:</strong><br>对于 exec 方法，即使在模式中使用了 g 标志，它每次也只会返回一个匹配项以及匹配项中的捕获组 <br>不设置 g 标志时，在同一个字符串上多词调用 exec 方法，则始终返回第一个匹配项信息 <br>设置 g 标志时，每次调用 exec 都会在字符串中<strong>继续</strong>查找新匹配！lastIndex 属性同时也跟着变化</p></blockquote><p>当一个组有多次匹配时，数组的匹配组只包含最后一个匹配</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> re </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/(</span><span style="color:#C3E88D;">\d</span><span style="color:#89DDFF;">)+/</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> matches </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> re</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">exec</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">123</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(matches) </span><span style="color:#676E95;font-style:italic;">// [&quot;123&quot;,&quot;3&quot;] // 匹配组只包含最后一个匹配字符</span></span>
<span class="line"></span></code></pre></div><h2 id="正则表达式构造函数属性" tabindex="-1">正则表达式构造函数属性 <a class="header-anchor" href="#正则表达式构造函数属性" aria-hidden="true">#</a></h2><p>RegExp 构造函数包含一些属性（静态属性），这些属性适用于作用域中的所有正则表达式，并且基于所执行的<strong>最近一次正则表达式操作(exec 或 test 方法)而定</strong>。</p><h3 id="属性列表-1" tabindex="-1">属性列表 <a class="header-anchor" href="#属性列表-1" aria-hidden="true">#</a></h3><p>这些属性可以通过两种方式访问它们</p><table><thead><tr><th>长属性名</th><th>短属性名</th><th>描述</th></tr></thead><tbody><tr><td>input</td><td>$_</td><td>最近一次要匹配的字符串</td></tr><tr><td>lastMatch</td><td>$&amp;</td><td>最近一次的匹配项</td></tr><tr><td>lastParen</td><td>$+</td><td>最近一次的捕获组</td></tr><tr><td>leftContext</td><td>$`</td><td>input 字符串中 lastMatch 之前的<strong>文本</strong></td></tr><tr><td>rightContext</td><td>$&#39;</td><td>input 字符串中 lastMatch 之后的<strong>文本</strong></td></tr><tr><td>$1 到$9</td><td>无</td><td>分别存储第一到第九个匹配的捕获组</td></tr></tbody></table><h3 id="示例" tabindex="-1">示例 <a class="header-anchor" href="#示例" aria-hidden="true">#</a></h3><p>请看下面示例</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> text </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">this has been a short number</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> pattern </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/(</span><span style="color:#C3E88D;">.</span><span style="color:#89DDFF;">)</span><span style="color:#C3E88D;">h</span><span style="color:#89DDFF;">(</span><span style="color:#C3E88D;">or</span><span style="color:#89DDFF;">)</span><span style="color:#C3E88D;">t</span><span style="color:#89DDFF;">/</span><span style="color:#F78C6C;">g</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> (pattern</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(text)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">RegExp</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">input</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// this has been a short number</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">RegExp</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">leftContext</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// this has been a</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">RegExp</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">rightContext</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// number</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">RegExp</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">lastMatch</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// short</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">RegExp</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">lastParen</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// or</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">RegExp</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">$1</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// s</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">RegExp</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">$2</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// or</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><h2 id="es6-新增特性" tabindex="-1">ES6 新增特性 <a class="header-anchor" href="#es6-新增特性" aria-hidden="true">#</a></h2><h3 id="实例新增-flags-属性" tabindex="-1">实例新增 flags 属性 <a class="header-anchor" href="#实例新增-flags-属性" aria-hidden="true">#</a></h3><p>flags 返回正则表达式的标志位（修饰符），如下</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> re </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">agc</span><span style="color:#89DDFF;">/</span><span style="color:#F78C6C;">gi</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(re</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">flags) </span><span style="color:#676E95;font-style:italic;">// gi</span></span>
<span class="line"></span></code></pre></div><h3 id="新增-u-修饰符" tabindex="-1">新增 u 修饰符 <a class="header-anchor" href="#新增-u-修饰符" aria-hidden="true">#</a></h3><p>在 ECMAScript 之前，js 一直基于 16 位字符编码（UTF-16）进行构建。</p><p>正则表达式中也默认将字符串中的每一个字符串按照 16 位编码单元处理</p><p>如𠮷字，它的 unicode 编码是 134071，超出了 16 位编码最大的 65535（0xffff），如果我们使用常规编码单元匹配模式，会不准确</p><p>添加了 u 修饰符后，正则表达式从编码单元操作模式切换为字符模式。</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> text </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">𠮷</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(text</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length) </span><span style="color:#676E95;font-style:italic;">// 2 ，是由2个16位编码单元组成</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;font-style:italic;">^</span><span style="color:#C3E88D;">.</span><span style="color:#89DDFF;font-style:italic;">$</span><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(text)) </span><span style="color:#676E95;font-style:italic;">// false 默认的匹配单个编码单元的方式无法匹配</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">/</span><span style="color:#89DDFF;font-style:italic;">^</span><span style="color:#C3E88D;">.</span><span style="color:#89DDFF;font-style:italic;">$</span><span style="color:#89DDFF;">/</span><span style="color:#F78C6C;">u</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(text)) </span><span style="color:#676E95;font-style:italic;">// true 使用u模式可以正确匹配</span></span>
<span class="line"></span></code></pre></div><h3 id="实例新增-unicode-属性" tabindex="-1">实例新增 unicode 属性 <a class="header-anchor" href="#实例新增-unicode-属性" aria-hidden="true">#</a></h3><p>返回模式是否使用了<code>u</code>修饰符</p><h3 id="新增-y-修饰符" tabindex="-1">新增 y 修饰符 <a class="header-anchor" href="#新增-y-修饰符" aria-hidden="true">#</a></h3><p>反映搜索是否具有粘性，即仅从正则表达式的 lastIndex 属性表示的索引处搜索</p><p>如果匹配失败，也不会继续向后搜索，并且会把 lastIndex 置为 0</p><p>请看下面示例：</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight" tabindex="0"><code><span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> text </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">abcd</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#C792EA;">let</span><span style="color:#A6ACCD;"> pat </span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">/</span><span style="color:#C3E88D;">bcd</span><span style="color:#89DDFF;">/</span><span style="color:#F78C6C;">y</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(pat</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">lastIndex) </span><span style="color:#676E95;font-style:italic;">// 0</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(pat</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(text)) </span><span style="color:#676E95;font-style:italic;">// false  因为从0开始并没有找到bcd</span></span>
<span class="line"><span style="color:#A6ACCD;">pat</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">lastIndex </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">// 让它从1开始匹配</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(pat</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">test</span><span style="color:#A6ACCD;">(text)) </span><span style="color:#676E95;font-style:italic;">// true 从1开始可以正确匹配到</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(pat</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">lastIndex) </span><span style="color:#676E95;font-style:italic;">// 4</span></span>
<span class="line"></span></code></pre></div><p>另外<code>y</code>和<code>g</code>一起使用，会忽略<code>g</code>标识符</p><h3 id="实例新增-stick-属性" tabindex="-1">实例新增 stick 属性 <a class="header-anchor" href="#实例新增-stick-属性" aria-hidden="true">#</a></h3><p>返回模式是否使用了<code>y</code>修饰符</p></div></div></main><!--[--><!--]--><footer class="VPDocFooter" data-v-c5936a1e data-v-e033cd21><div class="edit-info" data-v-e033cd21><!----><div class="last-updated" data-v-e033cd21><p class="VPLastUpdated" data-v-e033cd21 data-v-355aa5ef>更新时间: <time datetime="2023-03-01T15:45:52.000Z" data-v-355aa5ef></time></p></div></div><div class="prev-next" data-v-e033cd21><div class="pager" data-v-e033cd21><a class="pager-link prev" href="/blog/2020/07/throttle-and-debounce.html" data-v-e033cd21><span class="desc" data-v-e033cd21>前一篇</span><span class="title" data-v-e033cd21>节流和防抖技术</span></a></div><div class="has-prev pager" data-v-e033cd21><a class="pager-link next" href="/blog/2020/07/http-cache-and-nginx-config.html" data-v-e033cd21><span class="desc" data-v-e033cd21>下一篇</span><span class="title" data-v-e033cd21>http缓存与nginx配置</span></a></div></div></footer><!--[--><!--]--></div></div></div></div></div><!----><!--[--><!--]--></div></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"about_me.md\":\"a6963ed5\",\"about_contact.md\":\"753dd087\",\"blog_interviews_project-for-frontend-interview-questions-collection.md\":\"3ac3f621\",\"blog_svg_jiaohu.md\":\"bdc89024\",\"index.md\":\"ac84e241\",\"blog_svg_lujing.md\":\"2247252e\",\"blog_svg_lvjing.md\":\"7fb98f9e\",\"blog_svg_rumen.md\":\"760fcfc8\",\"blog_svg_tuanhejianbian.md\":\"1d67f731\",\"blog_svg_userspaceonuse-and-objectboundingbox.md\":\"7135675e\",\"blog_svg_wendangjiegou.md\":\"659e2114\",\"english_how.md\":\"47ca54fc\",\"blog_svg_zuobiaoxitong.md\":\"9f073aa7\",\"blog_svg_zuobiaoxitongbianhuan.md\":\"09c91562\",\"english_howtolearnword.md\":\"29e67a9c\",\"english_plan.md\":\"d3863f0d\",\"english_string.md\":\"afd02e54\",\"blog_interviews_css-for-frontend-interview-questions-collection.md\":\"ad8ec08c\",\"blog_interviews_index.md\":\"7922302b\",\"blog_interviews_javascript-for-frontend-interview-questions-collection.md\":\"1f97ba08\",\"blog_interviews_mian-shi-xin-de.md\":\"f249f58c\",\"blog_interviews_pingtouge-interview-questions-collection.md\":\"01898e13\",\"life_car_baoxian.md\":\"1a0484fd\",\"life_index.md\":\"294ee10b\",\"life_car_jiaotongshiguchuli.md\":\"2dfb478a\",\"life_car_kaiche.md\":\"fb68bff5\",\"photograph_fujifilm_renxiangpeifang.md\":\"df9d71f0\",\"photograph_fujifilm_jiappianjichu.md\":\"e4797107\",\"blog_readingnotes_browserprinciple.md\":\"5600b029\",\"blog_interviews_webpack-for-frontend-interview-questions-collection.md\":\"5e087073\",\"photograph_fujifilm_fengguangpeifang.md\":\"1f3c5cc8\",\"blog_summary_20210702.md\":\"992c6ebc\",\"blog_summary_20210716.md\":\"27df70fd\",\"blog_summary_20210723.md\":\"b3df6f63\",\"blog_summary_20210730.md\":\"0fd6c31f\",\"blog_readingnotes_jsgc4-2.md\":\"754107dd\",\"blog_summary_20210806.md\":\"8ede013a\",\"blog_svg_caijianhemengban.md\":\"345a71fa\",\"blog_readingnotes_jsgc4.md\":\"badec6ec\",\"blog_2020_07_accumulation-fund-transform.md\":\"ea36b833\",\"blog_svg_jibenxingzhuang.md\":\"3d07ebc2\",\"photograph_home.md\":\"289914d9\",\"photograph_fujifilm_xiangjishezhi.md\":\"c859f451\",\"photograph_sheyingzhishi.md\":\"7db1fab8\",\"photograph_xiangjixuanze.md\":\"b38cb6f4\",\"wemedia_what.md\":\"1d28f58c\",\"wemedia_emoji.md\":\"234e5631\",\"blog_2020_07_css-modules-docs.md\":\"4575442d\",\"blog_2020_07_git-docs.md\":\"22c9808c\",\"blog_2020_07_http-cache-and-nginx-config.md\":\"82b01b17\",\"blog_svg_donghua.md\":\"87326708\",\"blog_2020_06_gatsby-markdown-blog-system.md\":\"87de2558\",\"blog_2020_06_ubuntu14.04-install-nginx-for-source-code.md\":\"eff6df3c\",\"blog_2020_07_throttle-and-debounce.md\":\"745f9ff3\",\"blog_2020_07_regex-in-javascript.md\":\"375103f6\",\"blog_finance_income.md\":\"90b9a5cf\",\"blog_interviews_safe-for-frontend-interview-questions-collection.md\":\"6ae808c2\",\"blog_2020_07_vim-docs.md\":\"50a62a76\",\"blog_2020_08_fiddler.md\":\"29bf9a9b\",\"blog_2020_11_webpack-how-to-load-chunks.md\":\"2fc96bb0\",\"blog_2020_07_use-react-framework-web-site.md\":\"f836a6bd\",\"blog_interviews_algorithm-javascript.md\":\"72bdd42b\",\"blog_summary_20210611.md\":\"4cc8a1ab\",\"blog_summary_20210529.md\":\"fb886442\",\"blog_interviews_babel-for-frontend-interview-questions-collection.md\":\"495cb8da\",\"blog_summary_20210124.md\":\"ee3946e0\",\"blog_summary_20210619.md\":\"ef11c68e\",\"blog_summary_20210626.md\":\"5d8d583c\",\"blog_svg_wenben.md\":\"4aaeb73b\",\"blog_interviews_html-for-frontend-interview-questions-collection.md\":\"78197e40\",\"blog_interviews_react-for-frontend-interview-questions-collection.md\":\"90e3af48\",\"blog_interviews_http-for-frontend-interview-questions-collection.md\":\"1129730d\",\"blog_frontend_library.md\":\"34c972ff\",\"blog_readingnotes_reactandnodejs.md\":\"8a99114b\"}")</script>
    <script type="module" async src="/assets/app.6facf8ba.js"></script>
    
  </body>
</html>